﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using GIMS.Def.Interfaces;

namespace GIMS.Def.Settings
{
    public class GlobalSettings : IScriptPart
    {
        private static GlobalSettings instance;
        private static List<Setting> settings;
        public event PropertyChangedEventHandler PropertyChanged;

        private GlobalSettings()
        {
            settings = GetAllSettings();
            SubscribeEvents();
        }

        public static GlobalSettings Instance
        {
            get
            {
                if(instance==null)
                {
                    instance=new GlobalSettings();
                }
                return instance;
            }
        }

        private List<Setting> GetAllSettings()
        {
            List<Setting> result = new List<Setting>();
            Assembly a = Assembly.GetExecutingAssembly();
            Type settingType = typeof(Setting);

            IEnumerable<Type> types = a.GetTypes().Where(x => x.IsSubclassOf(settingType));

            foreach (var type in types)
            {   
                result.Add((Setting) Activator.CreateInstance(type));
            }
            return result;
        } 

        private void SubscribeEvents()
        {
            foreach ( Setting setting in settings)
            {
                setting.PropertyChanged += new PropertyChangedEventHandler(OnSettingChanged);
                setting.Argument.PropertyChanged += new PropertyChangedEventHandler(OnArgumentChanged);
            }
        }

        public List<Setting> Settings
        {
            get { return settings; }
        }

        public string CreateScriptPart()
        {
            string result = "";
            foreach (Setting setting in settings)
            {
                if (setting.Active)
                    result += string.Concat(" ", setting.CreateScriptPart());
            }
            return result.Trim();
        }

        private void OnArgumentChanged(object sender, EventArgs e)
        {
            NotifyPropertyChanged("Settings");
        }

        private void OnSettingChanged(object sender, EventArgs e)
        {
            NotifyPropertyChanged("Settings");
        }

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
